import { ChatContext } from '@/app/chat-context';
import { apiInterceptors, getAppInfo, getChatHistory, getDialogueList,newDialogue } from '@/client/api';
import useChat from '@/hooks/use-chat';
import ChatContentCompletion from './chatContentCompletion';
import ChatInputPanel from '@/new-components/chat/input/ChatInputPanel';
import ChatList from './ChatHistoryList';  //对话列表
import { IApp } from '@/types/app';
import { CloseOutlined, PlusOutlined, HistoryOutlined, SendOutlined } from '@ant-design/icons';
import { ChartData, ChatHistoryResponse, IChatDialogueSchema } from '@/types/chat';
import { getInitMessage } from '@/utils';
import { useAsyncEffect, useRequest } from 'ahooks';
import { Flex, Layout, Spin,Popover,Button } from 'antd';
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';

const { Content } = Layout;

interface CopilotChatContentProps {
  history: ChatHistoryResponse; // 会话记录列表
  replyLoading: boolean; // 对话回复loading
  scrollRef: React.RefObject<HTMLDivElement>; // 会话内容可滚动dom
  canAbort: boolean; // 是否能中断回复
  chartsData: ChartData[];
  agent: string;
  currentDialogue: IChatDialogueSchema; // 当前选择的会话
  appInfo: IApp;
  temperatureValue: any;
  maxNewTokensValue: any;
  resourceValue: any;
  modelValue: string;
  setModelValue: React.Dispatch<React.SetStateAction<string>>;
  setTemperatureValue: React.Dispatch<React.SetStateAction<any>>;
  setMaxNewTokensValue: React.Dispatch<React.SetStateAction<any>>;
  setResourceValue: React.Dispatch<React.SetStateAction<any>>;
  setAppInfo: React.Dispatch<React.SetStateAction<IApp>>;
  setAgent: React.Dispatch<React.SetStateAction<string>>;
  setCanAbort: React.Dispatch<React.SetStateAction<boolean>>;
  setReplyLoading: React.Dispatch<React.SetStateAction<boolean>>;
  handleChat: (content: string, data?: Record<string, any>) => Promise<void>; // 处理会话请求逻辑函数
  refreshDialogList: () => void;
  refreshHistory: () => void;
  refreshAppInfo: () => void;
  setHistory: React.Dispatch<React.SetStateAction<ChatHistoryResponse>>;
}
export const CopilotChatContext = createContext<CopilotChatContentProps>({
  history: [],
  replyLoading: false,
  scrollRef: { current: null },
  canAbort: false,
  chartsData: [],
  agent: '',
  currentDialogue: {} as any,
  appInfo: {} as any,
  temperatureValue: 0.5,
  maxNewTokensValue: 1024,
  resourceValue: {},
  modelValue: '',
  setModelValue: () => {},
  setResourceValue: () => {},
  setTemperatureValue: () => {},
  setMaxNewTokensValue: () => {},
  setAppInfo: () => {},
  setAgent: () => {},
  setCanAbort: () => {},
  setReplyLoading: () => {},
  refreshDialogList: () => {},
  refreshHistory: () => {},
  refreshAppInfo: () => {},
  setHistory: () => {},
  handleChat: () => Promise.resolve(),
});

const CopilotChat: React.FC = ({ setCopilotVisible,copilotParams,chat_scene,copilotType,fileId,copilotFileList }) => {
  localStorage.setItem('COPILOT_TYPE', copilotType);
  const { model, currentDialogInfo, setCurrentDialogInfo } = useContext(ChatContext);
//   const { isContract, setIsContract, setIsMenuExpand } = useContext(ChatContext);
  const { chat, ctrl } = useChat({
    app_code: chat_scene,
  });
  const dbName = copilotParams?.dataSourceData?.name ?? '';
  const scrollRef = useRef<HTMLDivElement>(null);
  const order = useRef<number>(1);

  const [chatId, setChatId] =  useState<string>('')
  const [scene, setScene] =  useState<string>(chat_scene)

  const [history, setHistory] = useState<ChatHistoryResponse>([]);
  const [chartsData] = useState<Array<ChartData>>();
  const [replyLoading, setReplyLoading] = useState<boolean>(false);
  const [canAbort, setCanAbort] = useState<boolean>(false);
  const [agent, setAgent] = useState<string>('');
  const [appInfo, setAppInfo] = useState<IApp>({} as IApp);
  const [temperatureValue, setTemperatureValue] = useState();
  const [maxNewTokensValue, setMaxNewTokensValue] = useState();
  const [resourceValue, setResourceValue] = useState<any>();
  const [modelValue, setModelValue] = useState<string>('');

  useEffect(() => {
    setTemperatureValue(appInfo?.param_need?.filter(item => item.type === 'temperature')[0]?.value || 0.6);
    setMaxNewTokensValue(appInfo?.param_need?.filter(item => item.type === 'max_new_tokens')[0]?.value || 4000);
    setModelValue(appInfo?.param_need?.filter(item => item.type === 'model')[0]?.value || model);
    setResourceValue(
       dbName || appInfo?.param_need?.filter(item => item.type === 'resource')[0]?.bind_value || [fileId],
    );
  }, [appInfo, dbName, model,fileId]);

  useEffect(() => {
    if (!chatId) {
     createNewChat();   
    }
  }, [chatId]);

  const isChatDefault = useMemo(() => {
    return !chatId && !scene;
  }, [chatId, scene]);

  // 获取会话列表
  const {
    data: dialogueList = [],
    refresh: refreshDialogList,
    loading: listLoading,
  } = useRequest(async () => {
    return await apiInterceptors(getDialogueList({chat_mode:chat_scene}));
  });

  // 获取应用详情
  const { run: queryAppInfo, refresh: refreshAppInfo } = useRequest(
    async () =>
      await apiInterceptors(
        getAppInfo({
          chat_scene: scene,
          app_code: scene
        }),
      ),
    {
      manual: true,
      onSuccess: data => {
        const [, res] = data;
        setAppInfo(res || ({} as IApp));
      },
    },
  );

  // 列表当前活跃对话
  const currentDialogue = useMemo(() => {
    const [, list] = dialogueList;
    const currentChat = list?.find(item => item.conv_uid === chatId) || ({} as IChatDialogueSchema);

    if(Object.keys(currentChat).length>0){ 
      return currentChat;
    }
    
  }, [chatId, dialogueList]);

  useEffect(() => {
    // const initMessage = getInitMessage();
    if ( scene && !isChatDefault) {
      queryAppInfo();
    }
  }, [chatId, isChatDefault, queryAppInfo, scene]);

  // 获取会话历史记录
  const {
    run: getHistory,
    loading: historyLoading,
    refresh: refreshHistory,
  } = useRequest(async () => await apiInterceptors(getChatHistory(chatId)), {
    manual: true,
    onSuccess: data => {
      const [, res] = data;
      setHistory(res || []);
      const viewList = res?.filter(item => item.role === 'view');
      if (viewList && viewList.length > 0) {
        order.current = viewList[viewList.length - 1].order + 1;
      }
      
    },
  });

  // 会话提问
  const handleChat = useCallback(
    (content: string, data?: Record<string, any>) => {
      return new Promise<void>(resolve => {
        // const initMessage = getInitMessage();
        const ctrl = new AbortController();
        setReplyLoading(true);
        if (history && history.length > 0) {
          const viewList = history?.filter(item => item.role === 'view');
          const humanList = history?.filter(item => item.role === 'human');
          order.current = (viewList[viewList.length - 1]?.order || humanList[humanList.length - 1]?.order) + 1;
        }
        const tempHistory: ChatHistoryResponse = [
          // ...(initMessage && initMessage.id === chatId ? [] : history),
          ...history,
          {
            role: 'human',
            context: content,
            model_name: data?.model_name || modelValue,
            order: order.current,
            time_stamp: 0,
          },
          {
            role: 'view',
            context: '',
            model_name: data?.model_name || modelValue,
            order: order.current,
            time_stamp: 0,
            thinking: true,
          },
        ];
        const index = tempHistory.length - 1;
        setHistory([...tempHistory]);
        chat({
          data: {
            chat_mode: scene,
            model_name: modelValue,
            user_input: content,
            ...data,
          },
          ctrl,
          chatId,
          onMessage: message => {
            setCanAbort(true);
            if (data?.incremental) {
              tempHistory[index].context += message;
              tempHistory[index].thinking = false;
            } else {
              tempHistory[index].context = message;
              tempHistory[index].thinking = false;
            }
            setHistory([...tempHistory]);
          },
          onDone: () => {
            setReplyLoading(false);
            setCanAbort(false);
            resolve();
          },
          onClose: () => {
            setReplyLoading(false);
            setCanAbort(false);
            resolve();
          },
          onError: message => {
            setReplyLoading(false);
            setCanAbort(false);
            tempHistory[index].context = message;
            tempHistory[index].thinking = false;
            setHistory([...tempHistory]);
            resolve();
          },
        });
      });
    },
    [chatId, history, modelValue, chat, scene],
  );

  // 修改 createNewChat 的实现
  const { run: createNewChat } = useRequest(
    async () => {
      const [, res] = await apiInterceptors(newDialogue({ chat_mode: scene }));
      if (res) {
        if (historyLoading) {
          return;
        }
        setChatId(res.conv_uid);
        setScene(res.chat_mode);
        setCurrentDialogInfo?.({
          conv_uid: res.conv_uid,
          chat_scene: res.chat_mode,
          app_code: res.chat_mode,
        });
        localStorage.setItem(
          'cur_dialog_info',
          JSON.stringify({
            chat_scene: res.chat_mode,
            app_code: res.chat_mode,
            conv_uid: res.conv_uid
          })
        );
        // localStorage.setItem(
        //   STORAGE_INIT_MESSAGE_KET, 
        //   JSON.stringify({ id: res.conv_uid, message: '' })
        // );
      }
    },
    {
      manual: true, // 手动触发
    }
  );

  // 查询当前选择的会话
  const handleSelectChat = async ({ scene, id }: { scene: string; id: string }) => {
    if (historyLoading) return;
    setChatId(id)
    setScene(scene)
    await getHistory();
  }

  useAsyncEffect(async () => {
    // 默认 不获取历史记录
    if (isChatDefault) {
      return;
    }
    const initMessage = getInitMessage();
    if (initMessage && initMessage.id === chatId) {
      return;
    }
    await getHistory();
  }, [chatId, scene, getHistory]);

  useEffect(() => {
    if (isChatDefault) {
      order.current = 1;
      setHistory([]);
    }
  }, [isChatDefault]);

  const contentRender = () => {
    return  (
        <Spin spinning={historyLoading} className='w-full h-full m-auto'>
            <Content className='flex flex-col h-screen'>
                {/* 对话内容 */}
                <ChatContentCompletion chatId={chatId} />
                {/* 对话输入框 */}
                <ChatInputPanel ctrl={ctrl} chatId={chatId} from={'copilot'} modelInfo={copilotParams?.modelInfo} copilotFileList={copilotFileList} />
            </Content>
        </Spin>
    )
  };

  return (
    <CopilotChatContext.Provider
      value={{
        history,
        replyLoading,
        scrollRef,
        canAbort,
        chartsData: chartsData || [],
        agent,
        currentDialogue,
        appInfo,
        temperatureValue,
        maxNewTokensValue,
        resourceValue,
        modelValue,
        setModelValue,
        setResourceValue,
        setTemperatureValue,
        setMaxNewTokensValue,
        setAppInfo,
        setAgent,
        setCanAbort,
        setReplyLoading,
        handleChat,
        refreshDialogList,
        refreshHistory,
        refreshAppInfo,
        setHistory,
      }}
    >
        <div className="flex-1 flex flex-col h-full border border-borderColor dark:border-darkBorderColor">
            {/* 标题栏 */}
            <div className="flex items-center justify-between px-4 py-2 border-b border-borderColor dark:border-darkBorderColor">
                <div className="text-lg font-semibold">NOAH Copilot</div>
                <div className="flex items-center space-x-2">
                    <Popover placement='top'  trigger='hover' content='创建新对话'>
                        <Button 
                            type="text" 
                            icon={<PlusOutlined />}
                            onClick={createNewChat}  
                        />
                    </Popover>
                    {/* 对话列表 */}
                    <Popover placement='top'  trigger='hover' content={
                        <ChatList
                            refresh={refreshDialogList}
                            dialogueList={dialogueList}
                            listLoading={listLoading}
                            historyLoading={historyLoading}
                            order={order}
                            scene={scene}
                            chatId={chatId}
                            onSelectChat={handleSelectChat}
                        />
                    }>
                        <Button  type="text" icon={<HistoryOutlined />} />
                    </Popover>
                    <Button 
                        type="text" 
                        icon={<CloseOutlined />}
                        onClick={() => {
                          setCopilotVisible(false);
                        }}
                    />
                </div>
            </div>
            <div className="flex-1 overflow-auto">
                <Layout className='bg-transparent'>
                    {contentRender()}
                </Layout>
            </div>
        </div>
    </CopilotChatContext.Provider>
  );
};

export default CopilotChat;
